#include <iostream>
#include <compare>
#include <string>
#include <vector>
#include <limits>
#include <cmath>

// 使用三路比较运算符的简单类
class Version {
private:
    int m_major_;
    int m_minor_;
    int m_patch_;

public:
    Version(int major, int minor, int patch) 
        : m_major_(major), m_minor_(minor), m_patch_(patch) {}
    
    // C++20默认提供的三路比较运算符
    auto operator<=>(const Version& other) const = default;
    
    // 为了演示目的，还需要相等运算符
    bool operator==(const Version& other) const = default;
    
    // 用于打印版本
    friend std::ostream& operator<<(std::ostream& os, const Version& v) {
        return os << v.m_major_ << "." << v.m_minor_ << "." << v.m_patch_;
    }
};

// 自定义三路比较运算符的示例
class CustomVersion {
private:
    int m_major_;
    int m_minor_;
    int m_patch_;
    std::string m_codename_;

public:
    CustomVersion(int major, int minor, int patch, std::string codename = "")
        : m_major_(major), m_minor_(minor), m_patch_(patch), m_codename_(codename) {}
    
    // 自定义三路比较运算符
    std::strong_ordering operator<=>(const CustomVersion& other) const {
        // 先比较主版本号
        if (auto cmp = m_major_ <=> other.m_major_; cmp != 0) {
            return cmp;
        }
        
        // 再比较次版本号
        if (auto cmp = m_minor_ <=> other.m_minor_; cmp != 0) {
            return cmp;
        }
        
        // 最后比较修订号
        return m_patch_ <=> other.m_patch_;
        
        // 注意：这里我们忽略了codename字段
    }
    
    // 仍然需要自定义相等运算符
    bool operator==(const CustomVersion& other) const {
        return m_major_ == other.m_major_ &&
               m_minor_ == other.m_minor_ &&
               m_patch_ == other.m_patch_;
        // 同样忽略codename以保持一致性
    }
    
    // 打印函数
    friend std::ostream& operator<<(std::ostream& os, const CustomVersion& v) {
        os << v.m_major_ << "." << v.m_minor_ << "." << v.m_patch_;
        if (!v.m_codename_.empty()) {
            os << " (" << v.m_codename_ << ")";
        }
        return os;
    }
};

// 演示三种比较结果
void print_comparison_result(const std::partial_ordering& result) {
    if (result == std::partial_ordering::less) {
        std::cout << " < ";
    } else if (result == std::partial_ordering::equivalent) {
        std::cout << " == ";
    } else if (result == std::partial_ordering::greater) {
        std::cout << " > ";
    } else {
        std::cout << " 无序 ";
    }
}

void demonstrate_three_way_comparison() {
    std::cout << "  C++20 三路比较(<=>, 太空舰船)运算符演示:\n\n";
    
    // 1. 基本用法
    std::cout << "  基本用法:\n";
    
    Version v1(1, 0, 0);
    Version v2(1, 1, 0);
    Version v3(1, 1, 0);
    
    std::cout << "  比较版本: " << v1 << " vs " << v2 << '\n';
    
    // 使用<=>运算符
    auto result1 = v1 <=> v2;
    std::cout << "  v1 <=> v2 结果: ";
    if (result1 < 0) {
        std::cout << "v1 < v2\n";
    } else if (result1 > 0) {
        std::cout << "v1 > v2\n";
    } else {
        std::cout << "v1 == v2\n";
    }
    
    // 使用==运算符
    std::cout << "  v2 == v3: " << std::boolalpha << (v2 == v3) << '\n';
    
    // 2. 编译器自动生成其他比较运算符
    std::cout << "\n  自动生成其他比较运算符:\n";
    
    // 这些运算符都是基于<=>自动生成的
    std::cout << "  v1 < v2: " << (v1 < v2) << '\n';
    std::cout << "  v1 <= v2: " << (v1 <= v2) << '\n';
    std::cout << "  v1 > v2: " << (v1 > v2) << '\n';
    std::cout << "  v1 >= v2: " << (v1 >= v2) << '\n';
    std::cout << "  v1 != v2: " << (v1 != v2) << '\n';
    
    // 3. 自定义三路比较
    std::cout << "\n  自定义三路比较运算符:\n";
    
    CustomVersion cv1(1, 2, 3, "Alpha");
    CustomVersion cv2(1, 2, 3, "Beta");
    CustomVersion cv3(2, 0, 0, "Release");
    
    std::cout << "  比较自定义版本:\n";
    std::cout << "  cv1 = " << cv1 << '\n';
    std::cout << "  cv2 = " << cv2 << '\n';
    std::cout << "  cv3 = " << cv3 << '\n';
    
    std::cout << "  cv1 == cv2: " << (cv1 == cv2) << " (忽略codename)\n";
    std::cout << "  cv1 < cv3: " << (cv1 < cv3) << '\n';
    std::cout << "  cv3 > cv2: " << (cv3 > cv2) << '\n';
    
    // 4. 不同的比较类别
    std::cout << "\n  不同的比较类别:\n";
    std::cout << "  std::strong_ordering: 表示全序关系 (如整数)\n";
    std::cout << "  std::weak_ordering: 表示弱序关系 (如不区分大小写的字符串)\n";
    std::cout << "  std::partial_ordering: 表示偏序关系 (如浮点数，可能存在NaN)\n";
    
    // 5. 浮点数比较示例
    std::cout << "\n  浮点数比较 (partial_ordering):\n";
    double a = 1.0;
    double b = 2.0;
    double nan = std::numeric_limits<double>::quiet_NaN();
    
    std::cout << "  1.0 <=> 2.0: ";
    print_comparison_result(a <=> b);
    std::cout << '\n';
    
    std::cout << "  2.0 <=> 1.0: ";
    print_comparison_result(b <=> a);
    std::cout << '\n';
    
    std::cout << "  1.0 <=> NaN: ";
    print_comparison_result(a <=> nan);
    std::cout << '\n';
    
    // 6. 三路比较相比传统方法的优势
    std::cout << "\n  三路比较的优势:\n";
    std::cout << "  - 简化代码: 只需定义一个运算符而不是6个\n";
    std::cout << "  - 一致性: 确保所有比较运算符的行为一致\n";
    std::cout << "  - 效率: 对于复杂对象，避免多次比较\n";
    std::cout << "  - 类型安全: 提供更强的类型检查\n";
    
    // 7. 与传统比较方式的对比
    std::cout << "\n  传统比较方式 vs 三路比较:\n";
    std::cout << "  传统方式:\n";
    std::cout << "    bool operator<(const T& other) const;\n";
    std::cout << "    bool operator<=(const T& other) const;\n";
    std::cout << "    bool operator>(const T& other) const;\n";
    std::cout << "    bool operator>=(const T& other) const;\n";
    std::cout << "    bool operator==(const T& other) const;\n";
    std::cout << "    bool operator!=(const T& other) const;\n";
    
    std::cout << "  三路比较:\n";
    std::cout << "    auto operator<=>(const T& other) const = default;\n";
    std::cout << "    bool operator==(const T& other) const = default; // 可选\n";
} 